home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2004 #9
/
Amiga Plus CD - 2004 - No. 09.iso
/
amigaplus
/
tools
/
amigaos4_only
/
fracblank
/
source
/
fracblank.c
< prev
next >
Wrap
C/C++ Source or Header
|
2004-08-03
|
27KB
|
939 lines
/*
** FracBlank - AmigaDOS 2.04 commodities utility screenblanker
**
** Copyright © 1991-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
**
** Cosmic flame fractal code derived from xlock source code
**
** Copyright © 1988-1991 by Patrick J. Naughton.
*/
#include <math.h>
#include <stdarg.h>
#include <string.h>
#include <dos/dos.h>
#include <exec/exec.h>
#include <graphics/gfxbase.h>
#include <intuition/intuition.h>
#include <intuition/pointerclass.h>
#include <libraries/asl.h>
#include <libraries/commodities.h>
#include <workbench/icon.h>
#include <proto/asl.h>
#include <proto/commodities.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/icon.h>
#include <proto/intuition.h>
#include <proto/keymap.h>
#include <proto/utility.h>
#include "Frac.h"
#include "FracBlank.h"
// Some useful signals
#define SIG_CX (1L << CxPort->mp_SigBit)
//define SIG_WINDOW (1L << Window->UserPort->mp_SigBit)
// A blank pointer
APTR Pointer;
UWORD Nothing;
struct BitMap PointerBitMap;
// The current colour mode
UBYTE ColourMode;
// The main program
struct Process *MainProcess;
BOOL PopUp;
// BlankerControl data
struct Process *BlankerControlProcess;
struct Hook ScreenHook,
WindowHook;
// BlankerEntry data
struct SignalSemaphore BlankSemaphore;
// Shared library identifiers
struct Library *CxBase,
*KeymapBase;
struct UtilityBase *UtilityBase;
struct CommoditiesIFace *ICommodities;
struct KeymapIFace *IKeymap;
struct UtilityIFace *IUtility;
// Prototypes for this module
struct Library *SafeOpenLibrary(STRPTR Name, LONG Version);
STRPTR ToolString(STRPTR *Array, STRPTR Match, STRPTR Default);
LONG ToolValue(STRPTR *Array, STRPTR Match, LONG Default);
ULONG BackfillDummy(VOID);
WORD GetSeconds(STRPTR String);
VOID CloseAll(LONG ReturnCode);
VOID OpenAll(int argc, char **argv);
VOID SaveOptions(char **argv);
VOID SPrintf(STRPTR Buffer, STRPTR FormatString, ...);
LONG Atol(STRPTR Buffer);
BOOL GetModeName(ULONG Mode, STRPTR Buffer);
VOID ReportError(struct Window *Window, STRPTR Template, LONG Error);
WORD ShowRequest(struct Window *Window, STRPTR Text, STRPTR Gadgets, ...);
/* main(int argc,char **argv):
*
* That's where all the trouble starts.
*/
int main(int argc, char **argv) {
ULONG SignalSet;
BOOL Done = FALSE;
// Set Defaults
ScreenTimeout = 60;
PatternTimeout = 60;
MaxRecursionLevel = 40;
MaxFlamePoints = 200;
// Open everything we need
OpenAll(argc,argv);
// Go into loop waiting for messages
do {
// Wait for a signal...
SignalSet = SIG_CX | SIG_BREAK | SIG_WAKEUP;
// if (Window) SignalSet |= SIG_WINDOW;
SignalSet = IExec->Wait(SignalSet);
// Check the commodities toolkit reply port
if (SignalSet & SIG_CX) {
CxMsg *Message;
while(Message = (CxMsg *)IExec->GetMsg(CxPort)) HandleCxMsg(Message);
}
// ^C tells the program to quit
if (SignalSet & SIG_BREAK) Done = TRUE;
// ^F tells the program to open its control panel
// if (SignalSet & SIG_WAKEUP) SetupWindow();
// If the control panel is still open,
// check for new messages.
// if (Window) Done = HandleWindowInput(SignalSet);
}
while(!Done);
CloseAll(RETURN_OK);
return(0);
}
/* ToolString(STRPTR *Array,STRPTR Match,STRPTR Default):
*
* Return the matching tooltype value, if available.
* Otherwise do with the default value.
*/
STRPTR ToolString(STRPTR *Array, STRPTR Match, STRPTR Default) {
if (Array) {
STRPTR String;
if (String = IIcon->FindToolType(Array,Match)) return(String);
}
return(Default);
}
/* ToolValue(STRPTR *Array,STRPTR Match,LONG Default):
*
* Return the matching tooltype value, if available.
* Otherwise do with the default value.
*/
LONG ToolValue(STRPTR *Array, STRPTR Match, LONG Default) {
if (Array) {
STRPTR String;
if (String = IIcon->FindToolType(Array,Match)) {
LONG Result;
if (IDOS->StrToLong(String,&Result) > 0) return(Result);
}
}
return(Default);
}
/* BackfillDummy():
*
* A no-op backfill routine, we'll clear the screen manually.
*/
ULONG BackfillDummy(VOID) { return(TRUE); }
/* GetSeconds(STRPTR String):
*
* Calculates the number of seconds corresponding to
* expressions such as `11:25' or `10'.
*/
WORD GetSeconds(STRPTR String) {
UBYTE Buffer[10];
WORD i,
Seconds;
IExec->CopyMem(String,Buffer,9);
Buffer[9] = 0;
String = Buffer;
for(i = strlen(String) - 1; i >= 0; i--) {
if (String[i] == ':') {
Seconds = Atol(&String[i + 1]);
String[i] = 0;
Seconds += 60 * Atol(String);
if (Seconds > 30 * 60) Seconds = 30 * 60;
return(Seconds);
}
}
if ((Seconds = Atol(String)) > 30 * 60) Seconds = 30 * 60;
return(Seconds);
}
/* CloseAll(LONG ReturnCode):
*
* Free all resources and exit the program.
*/
VOID CloseAll(LONG ReturnCode) {
// Wait until the screen is saved
while(Saver) IDOS->Delay(TICKS_PER_SECOND);
if (CxBase) ShutdownCx();
if (BlankerControlProcess) {
IExec->Forbid();
IExec->SetSignal(0,SIG_HANDSHAKE);
IExec->Signal((struct Task *)BlankerControlProcess,SIG_FINISH);
IExec->Wait(SIG_HANDSHAKE);
IExec->Permit();
}
if (Pointer) IIntuition->DisposeObject(Pointer);
//ShutdownWindow();
if (Colours) IExec->FreeVec(Colours);
if (ScreenModeRequest) IAsl->FreeAslRequest(ScreenModeRequest);
if (IKeymap) IExec->DropInterface((struct Interface *)IKeymap);
if (KeymapBase) IExec->CloseLibrary(KeymapBase);
if (ICommodities) IExec->DropInterface((struct Interface *)ICommodities);
if (CxBase) IExec->CloseLibrary(CxBase);
if (IUtility) IExec->DropInterface((struct Interface *)IUtility);
if (UtilityBase) IExec->CloseLibrary((struct Library *)UtilityBase);
exit(ReturnCode);
}
/* OpenAll(int argc,char **argv):
*
* Open all resources, initialize the colour table and
* create the Commodities interface.
*/
VOID OpenAll(int argc, char **argv) {
STRPTR *ToolTypes,
String,
Array[ARGCOUNT];
struct RDArgs *Args;
struct DiskObject *Icon;
IX Expression;
LONG Error;
// Initialize this, the rotation code needs it
deg45 = sin(-45.0);
ScreenHook.h_Entry = (HOOKFUNC)BackfillDummy;
WindowHook.h_Entry = (HOOKFUNC)BackfillDummy;
IExec->InitSemaphore(&BlankSemaphore);
MainProcess = (struct Process *)IExec->FindTask(NULL);
// Open the libraries we need
if (!(CxBase = IExec->OpenLibrary("commodities.library",50))) {
ReportError(NULL,NULL,ERR_NoCommodities);
CloseAll(RETURN_FAIL);
}
if (!(ICommodities = (struct CommoditiesIFace *)IExec->GetInterface(CxBase,"main",1,TAG_DONE))) {
ReportError(NULL,NULL,ERR_NoCommoditiesIFace);
CloseAll(RETURN_FAIL);
}
if (!(KeymapBase = IExec->OpenLibrary("keymap.library",50))) {
ReportError(NULL,NULL,ERR_NoKeymap);
CloseAll(RETURN_FAIL);
}
if (!(IKeymap = (struct KeymapIFace *)IExec->GetInterface(KeymapBase,"main",1,TAG_DONE))) {
ReportError(NULL,NULL,ERR_NoKeymapIFace);
CloseAll(RETURN_FAIL);
}
if (!(UtilityBase = (struct UtilityBase *)IExec->OpenLibrary("utility.library",50))) {
ReportError(NULL,NULL,ERR_NoKeymap);
CloseAll(RETURN_FAIL);
}
if (!(IUtility = (struct UtilityIFace *)IExec->GetInterface((struct Library *)UtilityBase,"main",1,TAG_DONE))) {
ReportError(NULL,NULL,ERR_NoUtilityIFace);
CloseAll(RETURN_FAIL);
}
if (!(ScreenModeRequest = (struct ScreenModeRequester *)IAsl->AllocAslRequestTags(ASL_ScreenModeRequest,
ASLSM_DoDepth, TRUE,
ASLSM_PropertyFlags, NULL,
ASLSM_PropertyMask, DIPF_IS_DUALPF | DIPF_IS_PF2PRI | DIPF_IS_HAM | DIPF_IS_EXTRAHALFBRITE,
ASLSM_MinDepth, 1,
ASLSM_MaxDepth, 8,
ASLSM_UserData, FALSE,
TAG_DONE))) {
ReportError(NULL,NULL,ERR_ScreenModeRequest);
CloseAll(RETURN_FAIL);
}
// Set up a transparent window pointer
IGraphics->InitBitMap(&PointerBitMap,2,16,1);
PointerBitMap.Planes[0] = PointerBitMap.Planes[1] = (PLANEPTR)&Nothing;
if (!(Pointer = IIntuition->NewObject(NULL,POINTERCLASS,
POINTERA_BitMap, &PointerBitMap,
POINTERA_XOffset, 0,
POINTERA_YOffset, 0,
POINTERA_WordWidth, 2,
TAG_DONE))) {
ReportError(NULL,NULL,ERR_NoPointer);
CloseAll(RETURN_FAIL);
}
if (!(Colours = (ColourTable *)IExec->AllocVec(sizeof(ColourTable) + 255 * sizeof(ColourEntry),MEMF_ANY | MEMF_CLEAR))) {
ReportError(NULL,NULL,ERR_NoColours);
CloseAll(RETURN_FAIL);
}
IExec->Forbid();
if (BlankerControlProcess = IDOS->CreateNewProcTags(NP_Name, "« FracBlank Control Process »",
NP_Priority, 100,
NP_Entry, BlankerControlEntry,
NP_StackSize, 4096,
NP_WindowPtr, -1,
TAG_DONE)) {
IExec->SetSignal(0,SIG_HANDSHAKE);
// Wait for handshake signal
IExec->Wait(SIG_HANDSHAKE);
}
IExec->Permit();
if (!BlankerControlProcess) {
ReportError(NULL,NULL,ERR_NoControlProcess);
CloseAll(RETURN_FAIL);
}
memset(Array,0,sizeof(Array));
if (argc) {
if (!(Args = IDOS->ReadArgs("CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/K,BLANKSCREEN/K,SAVESCREEN/K,FRACTAL/K,COLOUR/K,DISPLAYMODE/K,DEPTH/N/K,SCREENTIMEOUT/K,PATTERNTIMEOUT/K,MAXRECURSION/N/K,MAXDOTS/N/K",(LONG *)Array,NULL))) {
IDOS->PrintFault(IDOS->IoErr(),"FracBlank");
CloseAll(RETURN_FAIL);
}
ToolTypes = NULL;
Icon = NULL;
}
else {
struct WBStartup *Startup = (struct WBStartup *)argv;
BPTR OldDir;
Args = NULL;
OldDir = IDOS->CurrentDir(MainProcess->pr_HomeDir);
if (Icon = IIcon->GetDiskObject(Startup->sm_ArgList->wa_Name)) ToolTypes = (STRPTR *)Icon->do_ToolTypes;
else ToolTypes = NULL;
IDOS->CurrentDir(OldDir);
}
NewBroker.nb_Pri = ToolValue(ToolTypes,"CX_PRIORITY",Array[ARG_PRIORITY] ? *(LONG *)Array[ARG_PRIORITY] : 0);
// We'll put up a mask of qualifiers we don't want the blanker
// to stop at
SpecialQualifier = IEQUALIFIER_REPEAT;
// Set the Commodity popup hotkey if possible
strcpy(HotkeyBuffer,ToolString(ToolTypes,"CX_POPKEY",Array[ARG_POPKEY] ? Array[ARG_POPKEY] : (STRPTR)"shift f1"));
SpecialQualifier = AddQualifier(HotkeyBuffer,SpecialQualifier);
if (Error = ICommodities->ParseIX(HotkeyBuffer,&Expression)) {
ReportError(NULL,"Invalid CX_POPKEY specification\n%s",ERR_BadFilter);
CloseAll(RETURN_FAIL);
}
/* Determine the screen blanker hotkey. */
strcpy(BlankScreenBuffer,ToolString(ToolTypes,"BLANKSCREEN",Array[ARG_BLANKSCREEN] ? Array[ARG_BLANKSCREEN] : (STRPTR)"shift f2"));
SpecialQualifier = AddQualifier(BlankScreenBuffer,SpecialQualifier);
if (Error = ICommodities->ParseIX(BlankScreenBuffer,&Expression)) {
ReportError(NULL,"Invalid BLANKSCREEN specification\n%s",ERR_BadFilter);
CloseAll(RETURN_FAIL);
}
// Set the screen save hotkey
strcpy(SaveScreenBuffer,ToolString(ToolTypes,"SAVESCREEN",Array[ARG_SAVESCREEN] ? Array[ARG_SAVESCREEN] : (STRPTR)"shift f3"));
SpecialQualifier = AddQualifier(SaveScreenBuffer,SpecialQualifier);
if (Error = ICommodities->ParseIX(SaveScreenBuffer,&Expression)) {
ReportError(NULL,"Invalid SAVESCREEN specification\n%s",ERR_BadFilter);
CloseAll(RETURN_FAIL);
}
// Which fractal type?
String = ToolString(ToolTypes,"FRACTAL",Array[ARG_FRACTAL] ? Array[ARG_FRACTAL] : (STRPTR)"RANDOM");
if (IIcon->MatchToolValue(String,"REALPLANE") || IIcon->MatchToolValue(String,"REAL")) FractalType = FRACTAL_REAL_PLANE;
else {
if (IIcon->MatchToolValue(String,"COSMICFLAME") || IIcon->MatchToolValue(String,"COSMIC") || IIcon->MatchToolValue(String,"FLAME")) FractalType = FRACTAL_COSMIC_FLAME;
else FractalType = FRACTAL_RANDOM;
}
// Which colour mode?
String = ToolString(ToolTypes,"COLOUR",Array[ARG_COLOUR] ? Array[ARG_COLOUR] : (STRPTR)"CYCLE");
if (IIcon->MatchToolValue(String,"STATIC")) ColourMode = COLOUR_STATIC;
else ColourMode = COLOUR_CYCLE;
// Which display mode?
DisplayID = INVALID_ID;
if (String = ToolString(ToolTypes,"DISPLAYMODE",Array[ARG_DISPLAYMODE])) {
UBYTE LocalBuffer[40];
ULONG ID = INVALID_ID;
while((ID = IGraphics->NextDisplayInfo(ID)) != INVALID_ID) {
if (GetModeName(ID,LocalBuffer)) {
if (!IUtility->Stricmp(LocalBuffer,String)) {
struct DisplayInfo DisplayInfo;
if (IGraphics->GetDisplayInfoData(NULL,(APTR)&DisplayInfo,sizeof(struct DisplayInfo),DTAG_DISP,ID)) {
if (!(DisplayInfo.NotAvailable & ~DI_AVAIL_NOTWITHGENLOCK)) {
if (!(DisplayInfo.PropertyFlags & (DIPF_IS_DUALPF | DIPF_IS_PF2PRI | DIPF_IS_HAM | DIPF_IS_EXTRAHALFBRITE))) {
DisplayID = ID;
break;
}
}
}
}
}
}
}
// Which depth?
Depth = ToolValue(ToolTypes,"DEPTH",Array[ARG_DEPTH] ? *(LONG *)Array[ARG_DEPTH] : 0);
if (Depth > 8) Depth = 8;
else {
if (Depth < 0) Depth = 0;
}
// Adjust the screen timeout if possible
ScreenTimeout = GetSeconds(ToolString(ToolTypes,"SCREENTIMEOUT",Array[ARG_SCREENTIMEOUT] ? Array[ARG_SCREENTIMEOUT] : (STRPTR)"1:00"));
// Adjust the pattern change timeout
PatternTimeout = GetSeconds(ToolString(ToolTypes,"PATTERNTIMEOUT",Array[ARG_PATTERNTIMEOUT] ? Array[ARG_PATTERNTIMEOUT] : (STRPTR)"1:00"));
// Take care of the recursion level
MaxRecursionLevel = ToolValue(ToolTypes,"MAXRECURSION",Array[ARG_MAXRECURSION] ? *(LONG *)Array[ARG_MAXRECURSION] : 40);
if (MaxRecursionLevel < 10) MaxRecursionLevel = 10;
else {
if (MaxRecursionLevel > 100) MaxRecursionLevel = 100;
}
// Now for the cosmic flame dots
MaxFlamePoints = ToolValue(ToolTypes,"MAXDOTS",Array[ARG_MAXDOTS] ? *(LONG *)Array[ARG_MAXDOTS] : 20000);
MaxFlamePoints /= 100;
if (MaxFlamePoints < 10) MaxFlamePoints = 10;
else {
if (MaxFlamePoints > 1000) MaxFlamePoints = 1000;
}
// Create the commodities interface
if (Error = SetupCx()) {
if (Error != ERR_Duplicate) ReportError(NULL,NULL,Error);
if (Args) IDOS->FreeArgs(Args);
if (Icon) IIcon->FreeDiskObject(Icon);
CloseAll(RETURN_FAIL);
}
// Pop up the control panel if necessary
//if (MatchToolValue(ToolString(ToolTypes,"CX_POPUP",Array[ARG_POPUP] ? Array[ARG_POPUP] : (STRPTR)"no"),"yes")) {
// PopUp = TRUE;
// SetupWindow();
//}
// Clean up
if (Args) IDOS->FreeArgs(Args);
if (Icon) IIcon->FreeDiskObject(Icon);
}
/* SaveOptions(char **argv):
*
* Here we store the current options within the program icon.
*/
VOID SaveOptions(char **argv) {
static STRPTR KnownTypes[] = {
"CX_PRIORITY",
"CX_POPKEY",
"CX_POPUP",
"BLANKSCREEN",
"SAVESCREEN",
"FRACTAL",
"COLOUR",
"DISPLAYMODE",
"DEPTH",
"SCREENTIMEOUT",
"PATTERNTIMEOUT",
"MAXRECURSION",
"MAXDOTS"
};
BPTR OldDir;
struct WBStartup *Startup = (struct WBStartup *)argv;
struct DiskObject *Icon;
OldDir = IDOS->CurrentDir(MainProcess->pr_HomeDir);
// Get the program icon
if (Icon = IIcon->GetDiskObject(Startup->sm_ArgList->wa_Name)) {
STRPTR *Types,
*NewTypes,
Data;
LONG Count = 0,
Known = sizeof(KnownTypes) / sizeof(STRPTR),Len = 0,
i;
// Count the number of tooltypes present
if (Types = (STRPTR *)Icon->do_ToolTypes) {
while(Types[Count]) Count++;
}
// Count the room required for the tooltypes to add
for(i = 0; i < Known; i++) Len += strlen(KnownTypes[i]) + 2;
// Add room for the keys
Len += (10) + (256) + (4) + (256) + (256) + (8) + (8) + (40) + (10) + (10) + (10) + (10) + (10);
// All the data will go here
if (NewTypes = (STRPTR *)IExec->AllocVec(Len + (Count + 1 + Known) * sizeof(STRPTR),MEMF_ANY | MEMF_CLEAR)) {
STRPTR *Tool = NewTypes,
String;
UBYTE LocalBuffer[DISPLAYNAMELEN];
Data = (STRPTR)&NewTypes[Count + 1 + Known];
// CX_PRIORITY=[..]
SPrintf(Data,"CX_PRIORITY=%ld",NewBroker.nb_Pri);
*Tool++ = Data;
Data += strlen(Data) + 1;
// CX_POPKEY=[..]
SPrintf(Data,"CX_POPKEY=%s",HotkeyBuffer);
*Tool++ = Data;
Data += strlen(Data) + 1;
// CX_POPUP=[..]
SPrintf(Data,"CX_POPUP=%s",PopUp ? "yes" : "no");
*Tool++ = Data;
Data += strlen(Data) + 1;
// BLANKSCREEN=[..]
SPrintf(Data,"BLANKSCREEN=%s",BlankScreenBuffer);
*Tool++ = Data;
Data += strlen(Data) + 1;
// SAVESCREEN=[..]
SPrintf(Data,"SAVESCREEN=%s",SaveScreenBuffer);
*Tool++ = Data;
Data += strlen(Data) + 1;
// FRACTAL=[..]
switch(FractalType) {
case FRACTAL_REAL_PLANE:
String = "REALPLANE";
break;
case FRACTAL_COSMIC_FLAME:
String = "COSMICFLAME";
break;
case FRACTAL_RANDOM:
String = "RANDOM";
break;
}
SPrintf(Data,"FRACTAL=%s",String);
*Tool++ = Data;
Data += strlen(Data) + 1;
// COLOUR=[..]
switch(ColourMode) {
case COLOUR_CYCLE:
String = "CYCLE";
break;
case COLOUR_STATIC:
String = "STATIC";
break;
}
SPrintf(Data,"COLOUR=%s",String);
*Tool++ = Data;
Data += strlen(Data) + 1;
// DISPLAYMODE=[..]
if (GetModeName(DisplayID,LocalBuffer)) {
SPrintf(Data,"DISPLAYMODE=%s",LocalBuffer);
*Tool++ = Data;
Data += strlen(Data) + 1;
}
// DEPTH=[..]
SPrintf(Data,"DEPTH=%ld",Depth);
*Tool++ = Data;
Data += strlen(Data) + 1;
// SCREENTIMEOUT=[..]
SPrintf(Data,"SCREENTIMEOUT=%ld:%02ld",ScreenTimeout / 60,ScreenTimeout % 60);
*Tool++ = Data;
Data += strlen(Data) + 1;
// PATTERNTIMEOUT=[..]
SPrintf(Data,"PATTERNTIMEOUT=%ld:%02ld",PatternTimeout / 60,PatternTimeout % 60);
*Tool++ = Data;
Data += strlen(Data) + 1;
// MAXRECURSION=[..]
SPrintf(Data,"MAXRECURSION=%ld",MaxRecursionLevel);
*Tool++ = Data;
Data += strlen(Data) + 1;
// MAXDOTS=[..]
SPrintf(Data,"MAXDOTS=%ld",MaxFlamePoints * 100);
*Tool++ = Data;
// Now add the remaining old tooltypes,
// unless we already took care of them
if (Types = (STRPTR *)Icon->do_ToolTypes) {
BOOL GotIt;
while(*Types) {
GotIt = FALSE;
for(i = 0; i < Known; i++) {
if (!IUtility->Strnicmp(*Types,KnownTypes[i],strlen(KnownTypes[i]))) {
GotIt = TRUE;
break;
}
}
if (!GotIt) *Tool++ = *Types;
Types++;
}
}
// Install the new tooltypes
Icon->do_ToolTypes = (STRPTR *)NewTypes;
// Write the icon
// if (!IIcon->PutDiskObject(Startup->sm_ArgList->wa_Name,Icon)) ReportError(Window,"Error writing icon\n%s",IDOS->IoErr());
// Clean up
IExec->FreeVec(NewTypes);
}
// else ReportError(Window,NULL,ERROR_NO_FREE_STORE);
IIcon->FreeDiskObject(Icon);
}
//else ReportError(Window,"Error reading icon\n%s",IoErr());
IDOS->CurrentDir(OldDir);
}
/* SafeOpenLibrary(STRPTR Name,LONG Version):
*
* Just like OpenLibrary, but makes sure that old
* library versions get flushed from memory.
*/
struct Library *SafeOpenLibrary(STRPTR Name, LONG Version) {
/*
struct Library *Base;
IExec->Forbid();
if (Base = (struct Library *)IExec->FindName(&SysBase->LibList,IDOS->FilePart(Name))) {
if(Base->lib_Version < Version) IExec->RemLibrary(Base);
}
IExec->Permit();
*/
return(IExec->OpenLibrary(Name,Version));
}
/* SPrintf(STRPTR Buffer,STRPTR FormatString,...):
*
* String formatting routine, similar to sprintf().
*/
VOID SPrintf(STRPTR Buffer, STRPTR FormatString, ...) {
va_list VarArgs;
va_start(VarArgs,FormatString);
IUtility->VSNPrintf(Buffer,sizeof(Buffer),FormatString,VarArgs);
va_end(VarArgs);
}
/* Atol(STRPTR Buffer):
*
* Convert a string into a long word.
*/
LONG Atol(STRPTR Buffer) {
LONG Result;
IDOS->StrToLong(Buffer,&Result);
return(Result);
}
/* GetModeName(ULONG Mode,STRPTR Buffer):
*
* This routine supplies the name for a DisplayID.
*/
BOOL GetModeName(ULONG Mode, STRPTR Buffer) {
struct NameInfo NameInfo;
if (IGraphics->GetDisplayInfoData(NULL,(APTR)&NameInfo,sizeof(struct NameInfo),DTAG_NAME,Mode)) strcpy(Buffer,NameInfo.Name);
else {
struct DisplayInfo DisplayInfo;
if (IGraphics->GetDisplayInfoData(NULL,(APTR)&DisplayInfo,sizeof(struct DisplayInfo),DTAG_DISP,Mode)) {
struct DimensionInfo DimensionInfo;
if (IGraphics->GetDisplayInfoData(NULL,(APTR)&DimensionInfo,sizeof(struct DimensionInfo),DTAG_DIMS,Mode)) {
STRPTR MonitorName;
switch(Mode & MONITOR_ID_MASK) {
case NTSC_MONITOR_ID:
MonitorName = "NTSC:";
break;
case PAL_MONITOR_ID:
MonitorName = "PAL:";
break;
case VGA_MONITOR_ID:
MonitorName = "VGA:";
break;
case A2024_MONITOR_ID:
MonitorName = "A2024:";
break;
default:
MonitorName = "";
break;
}
if (DisplayInfo.PropertyFlags & DIPF_IS_HAM) {
SPrintf(Buffer,"%s%ld × %ld HAM",MonitorName,DimensionInfo.TxtOScan.MaxX - DimensionInfo.TxtOScan.MinX + 1,DimensionInfo.TxtOScan.MaxY - DimensionInfo.TxtOScan.MinY + 1);
}
else {
SPrintf(Buffer,"%s%ld × %ld",MonitorName,DimensionInfo.TxtOScan.MaxX - DimensionInfo.TxtOScan.MinX + 1,DimensionInfo.TxtOScan.MaxY - DimensionInfo.TxtOScan.MinY + 1);
}
}
else return(FALSE);
}
else return(FALSE);
}
return(TRUE);
}
/* ReportError(struct Window *Window,STRPTR Template,LONG Error):
*
* Show an error message.
*/
VOID ReportError(struct Window *Window, STRPTR Template, LONG Error) {
static struct {
LONG Error;
STRPTR Code;
} Table[] = {
ERR_SystemError, "Commodities system error; out of memory",
ERR_Duplicate, "Commodities broker already exists",
ERR_Version, "Commodities broker version not supported",
ERR_BadFilter, "Bad filter descriptor",
ERR_BadType, "Bad type descriptor",
ERR_NoIntuition, "Could not open intuition.library v37",
ERR_NoGfx, "Could not open graphics.library v39",
ERR_NoAsl, "Could not open asl.library v38",
ERR_NoCommodities, "Could not open commodities.library v50",
ERR_NoCommoditiesIFace,"Could not open commodities main interface v1",
ERR_NoUtility, "Could not open utility.library v50",
ERR_NoUtilityIFace, "Could not open utility main interface v1",
ERR_NoIcon, "Could not open icon.library v37",
ERR_ScreenModeRequest, "Could not allocate screen mode requester",
ERR_NoColours, "Could not allocate colour table; out of memory",
ERR_NoPointer, "Could not allocate mouse pointer; out of memory",
ERR_NoControlProcess, "Could not create mouse blanker process",
ERR_NoMsgPort, "Could not create message port",
ERR_NoWindow, "Could not open window",
ERR_NoKeymap, "Could not open keymap.library v50",
ERR_NoKeymapIFace, "Could not open keymap interface v1",
ERR_NoGTLayout, "Could not open gtlayout.library v9",
0,
NULL
};
UBYTE LocalBuffer[256];
STRPTR Buffer;
BOOL GotIt = FALSE;
LONG i;
// Look for the corresponding error message.
for(i = 0; Table[i].Error; i++) {
if (Error == Table[i].Error) {
Buffer = Table[i].Code;
GotIt = TRUE;
break;
}
}
if (!GotIt) {
if (!IDOS->Fault(Error,"",LocalBuffer,256)) return;
Buffer = &LocalBuffer[2];
}
if (!Template) Template = Buffer;
if (MainProcess->pr_CLI && !Window) {
IDOS->Printf("FracBlank: ");
IDOS->Printf(Template,Buffer);
IDOS->Printf("\n");
}
else ShowRequest(Window,Template,"Continue",Buffer);
}
/* ShowRequest(struct Window *Window,STRPTR Text,STRPTR Gadgets,...):
*
* This routine shows an easy requester. If there is just one
* button to be pressed, the user will be able to answer it
* by pressing any key.
*/
WORD ShowRequest(struct Window *Window, STRPTR Text, STRPTR Gadgets, ...) {
if (IntuitionBase) {
struct EasyStruct Easy;
va_list VarArgs;
LONG i,
GadgetCount;
for(i = GadgetCount = 0; i < strlen(Gadgets); i++) {
if (Gadgets[i] == '|') GadgetCount++;
}
Easy.es_StructSize = sizeof(struct EasyStruct);
Easy.es_Flags = 0;
Easy.es_Title = "Fractal screen blanker";
Easy.es_TextFormat = Text;
Easy.es_GadgetFormat = Gadgets;
if (GadgetCount) {
WORD Result;
// if (GTLayoutBase) LT_LockWindow(Window);
va_start(VarArgs,Gadgets);
Result = IIntuition->EasyRequestArgs(Window,&Easy,NULL,VarArgs);
va_end(VarArgs);
// if (GTLayoutBase) LT_UnlockWindow(Window);
return(Result);
}
else {
struct Window *ReqWindow;
// if (GTLayoutBase) LT_LockWindow(Window);
va_start(VarArgs,Gadgets);
if (ReqWindow = IIntuition->BuildEasyRequestArgs(Window,&Easy,IDCMP_RAWKEY,VarArgs)) {
ULONG IDCMP;
LONG Result;
for(;;) {
IExec->WaitPort(ReqWindow->UserPort);
IDCMP = 0;
Result = IIntuition->SysReqHandler(ReqWindow,&IDCMP,FALSE);
if (!Result || (Result == -2 && !(IDCMP & IDCMP_RAWKEY))) break;
}
IIntuition->FreeSysRequest(ReqWindow);
}
va_end(VarArgs);
// if (GTLayoutBase) LT_UnlockWindow(Window);
}
}
return(0);
}